//
// Created by suzhen on 2019-03-30.
//

#include "chan_buffer.h"

namespace qio {

void ChanBuffer::Write(const char *data, std::size_t n) QIO_NOEXCEPT {
  std::copy_n(data, n, std::back_inserter(data_));
}

void ChanBuffer::Write(const Buffer::DataType &data) QIO_NOEXCEPT {
  Write(data.data(), data.size());
}

Buffer::DataType ChanBuffer::Read(std::size_t n) QIO_NOEXCEPT {
  DataType out(n);
  std::copy_n(data_.begin(), n, out.begin());
  Pop(n);
  return out;
}

std::int8_t ChanBuffer::PeekInt8(int offset) const QIO_NOEXCEPT {
  return Peek<std::int8_t>(offset);
}

std::uint8_t ChanBuffer::PeekUInt8(int offset) const QIO_NOEXCEPT {
  return Peek<std::uint8_t>(offset);
}

std::int16_t ChanBuffer::PeekInt16(int offset) const QIO_NOEXCEPT {
  return Peek<std::int16_t>(offset);
}

std::uint16_t ChanBuffer::PeekUInt16(int offset) const QIO_NOEXCEPT {
  return Peek<std::uint16_t>(offset);
}

std::int32_t ChanBuffer::PeekInt32(int offset) const QIO_NOEXCEPT {
  return Peek<std::int32_t>(offset);
}

std::uint32_t ChanBuffer::PeekUInt32(int offset) const QIO_NOEXCEPT {
  return Peek<std::uint32_t>(offset);
}

std::int8_t ChanBuffer::ReadInt8() QIO_NOEXCEPT { return Read<std::int8_t>(); }

std::uint8_t ChanBuffer::ReadUInt8() QIO_NOEXCEPT {
  return Read<std::uint8_t>();
}

std::uint16_t ChanBuffer::ReadUInt16() QIO_NOEXCEPT {
  return Read<std::uint16_t>();
}

std::int16_t ChanBuffer::ReadInt16() QIO_NOEXCEPT {
  return Read<std::int16_t>();
}

std::int32_t ChanBuffer::ReadInt32() QIO_NOEXCEPT {
  return Read<std::int32_t>();
}

std::uint32_t ChanBuffer::ReadUInt32() QIO_NOEXCEPT {
  return Read<std::uint32_t>();
}

Buffer::DataType ChanBuffer::ReadAll() QIO_NOEXCEPT {
  DataType dt;
  data_.swap(dt);
  return dt;
}

void ChanBuffer::WriteInt8(std::int8_t i) QIO_NOEXCEPT {
  data_.emplace_back((char)i);
}

void ChanBuffer::WriteUInt8(std::uint8_t i) QIO_NOEXCEPT {
  data_.emplace_back((char)i);
}

void ChanBuffer::WriteInt16(std::int16_t i) QIO_NOEXCEPT {
  this->Write<std::int16_t>(i);
}

void ChanBuffer::WriteUInt16(std::uint16_t i) QIO_NOEXCEPT {
  this->Write<std::uint16_t>(i);
}

void ChanBuffer::WriteInt32(std::int32_t i) QIO_NOEXCEPT {
  this->Write<std::int32_t>(i);
}

void ChanBuffer::WriteUInt32(std::uint32_t i) QIO_NOEXCEPT {
  this->Write<std::uint32_t>(i);
}

std::size_t ChanBuffer::GetReadableLength() const QIO_NOEXCEPT {
  return data_.size();
}

void ChanBuffer::Pop(std::size_t n) QIO_NOEXCEPT {
  data_.erase(data_.begin(), data_.begin() + n);
}

Buffer::DataType ChanBuffer::Peek(int offset,
                                  std::size_t n) const QIO_NOEXCEPT {
  Buffer::DataType ret(n);
  std::copy_n(data_.begin() + offset, n, ret.begin());
  return ret;
}

}  // namespace qio